listitemfactory: Simplify
authorBenjamin Otte <otte@redhat.com>
Sun, 3 Nov 2019 01:23:46 +0000 (02:23 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 30 May 2020 23:26:46 +0000 (19:26 -0400)
Instead of 6 vfuncs, we now have 3 and rely on the factory keeping track
of what it needs to do.

We're doing lots of dancing from one object to another here, but this
will hopefully get simpler with further commits.

gtk/gtkbuilderlistitemfactory.c
gtk/gtkfunctionslistitemfactory.c
gtk/gtklistitem.c
gtk/gtklistitemfactory.c
gtk/gtklistitemfactoryprivate.h
gtk/gtklistitemprivate.h
gtk/gtklistitemwidget.c
gtk/gtklistitemwidgetprivate.h
gtk/gtksignallistitemfactory.c

index 12048d61e7f481c09135a58419a9bd73e293c48b..d3e5079e59b819bd669a070f40fca64f8adae8b0 100644 (file)
@@ -84,13 +84,14 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
 
 static void
 gtk_builder_list_item_factory_setup (GtkListItemFactory *factory,
+                                     GtkListItemWidget  *widget,
                                      GtkListItem        *list_item)
 {
   GtkBuilderListItemFactory *self = GTK_BUILDER_LIST_ITEM_FACTORY (factory);
   GtkBuilder *builder;
   GError *error = NULL;
 
-  GTK_LIST_ITEM_FACTORY_CLASS (gtk_builder_list_item_factory_parent_class)->setup (factory, list_item);
+  GTK_LIST_ITEM_FACTORY_CLASS (gtk_builder_list_item_factory_parent_class)->setup (factory, widget, list_item);
 
   builder = gtk_builder_new ();
 
index 41b708e36ef899e8dceff8826eeef7f0331040e5..2f179c332df0f31ba931823b7b02527db930738c 100644 (file)
@@ -43,18 +43,23 @@ G_DEFINE_TYPE (GtkFunctionsListItemFactory, gtk_functions_list_item_factory, GTK
 
 static void
 gtk_functions_list_item_factory_setup (GtkListItemFactory *factory,
+                                       GtkListItemWidget  *widget,
                                        GtkListItem        *list_item)
 {
   GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory);
 
-  GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->setup (factory, list_item);
-
   if (self->setup_func)
     self->setup_func (list_item, self->user_data);
+
+  GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->setup (factory, widget, list_item);
+
+  if (gtk_list_item_get_item (list_item) != NULL && self->bind_func)  
+    self->bind_func (list_item, self->user_data);
 }
 
 static void                  
 gtk_functions_list_item_factory_update (GtkListItemFactory *factory,
+                                        GtkListItemWidget  *widget,
                                         GtkListItem        *list_item,
                                         guint               position,
                                         gpointer            item,
@@ -62,7 +67,7 @@ gtk_functions_list_item_factory_update (GtkListItemFactory *factory,
 {
   GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory);
 
-  GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->update (factory, list_item, position, item, selected);
+  GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected);
 
   if (item != NULL && self->bind_func)  
     self->bind_func (list_item, self->user_data);
index ee50eb42ab9939e90af0f5b694c8d10c71fa6cc0..79d3e12e78ccc16344827723ba9e0f69c75ea70f 100644 (file)
@@ -239,17 +239,10 @@ gtk_list_item_init (GtkListItem *self)
 }
 
 GtkListItem *
-gtk_list_item_new (GtkListItemWidget *owner)
+gtk_list_item_new (void)
 {
-  GtkListItem *result;
-
-  g_return_val_if_fail (owner != NULL, NULL);
-
-  result = g_object_new (GTK_TYPE_LIST_ITEM,
-                         NULL);
-  result->owner = owner;
-
-  return result;
+  return g_object_new (GTK_TYPE_LIST_ITEM,
+                       NULL);
 }
 
 /**
index ca65639c55e4f20a4cd3171f2ce41c1c6d3aaf2d..83fdb08193fbf5da64d87b8d18568b2b12b4747d 100644 (file)
@@ -75,29 +75,31 @@ G_DEFINE_TYPE (GtkListItemFactory, gtk_list_item_factory, G_TYPE_OBJECT)
 
 static void
 gtk_list_item_factory_default_setup (GtkListItemFactory *self,
+                                     GtkListItemWidget  *widget,
                                      GtkListItem        *list_item)
 {
+  gtk_list_item_widget_default_setup (widget, list_item);
 }
 
 static void
 gtk_list_item_factory_default_teardown (GtkListItemFactory *self,
+                                        GtkListItemWidget  *widget,
                                         GtkListItem        *list_item)
 {
-  gtk_list_item_set_child (list_item, NULL);
-  gtk_list_item_set_selectable (list_item, TRUE);
+  gtk_list_item_widget_default_teardown (widget, list_item);
 
+  gtk_list_item_set_child (list_item, NULL);
 }
 
 static void                  
 gtk_list_item_factory_default_update (GtkListItemFactory *self,
+                                      GtkListItemWidget  *widget,
                                       GtkListItem        *list_item,
                                       guint               position,
                                       gpointer            item,
                                       gboolean            selected)
 {
-  gtk_list_item_set_item (list_item, item);
-  gtk_list_item_set_position (list_item, position);
-  gtk_list_item_set_selected (list_item, selected);
+  gtk_list_item_widget_default_update (widget, list_item, position, item, selected);
 }
 
 static void
@@ -115,35 +117,49 @@ gtk_list_item_factory_init (GtkListItemFactory *self)
 
 void
 gtk_list_item_factory_setup (GtkListItemFactory *self,
-                             GtkListItem        *list_item)
+                             GtkListItemWidget  *widget)
 {
+  GtkListItem *list_item;
+
   g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
 
-  GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->setup (self, list_item);
+  list_item = gtk_list_item_new ();
+
+  GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->setup (self, widget, list_item);
 }
 
 void
 gtk_list_item_factory_teardown (GtkListItemFactory *self,
-                                GtkListItem        *list_item)
+                                GtkListItemWidget  *widget)
 {
+  GtkListItem *list_item;
+
   g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
 
-  GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->teardown (self, list_item);
+  list_item = gtk_list_item_widget_get_list_item (widget);
+
+  GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->teardown (self, widget, list_item);
+
+  g_object_unref (list_item);
 }
 
 void
 gtk_list_item_factory_update (GtkListItemFactory *self,
-                              GtkListItem        *list_item,
+                              GtkListItemWidget  *widget,
                               guint               position,
                               gpointer            item,
                               gboolean            selected)
 {
+  GtkListItem *list_item;
+
   g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
-  g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+  g_return_if_fail (GTK_IS_LIST_ITEM_WIDGET (widget));
+
+  list_item = gtk_list_item_widget_get_list_item (widget);
 
   g_object_freeze_notify (G_OBJECT (list_item));
 
-  GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->update (self, list_item, position, item, selected);
+  GTK_LIST_ITEM_FACTORY_GET_CLASS (self)->update (self, widget, list_item, position, item, selected);
 
   g_object_thaw_notify (G_OBJECT (list_item));
 }
index 4cb49e88216260e5d47c4aa205e892d469ce8e0c..3ee5e5f088cf20e30b849c255c7e580a51d351fc 100644 (file)
@@ -22,8 +22,7 @@
 #define __GTK_LIST_ITEM_FACTORY_PRIVATE_H__
 
 #include <gtk/gtklistitem.h>
-#include <gtk/gtklistitemfactory.h>
-#include <gtk/gtklistview.h>
+#include "gtk/gtklistitemwidgetprivate.h"
 
 G_BEGIN_DECLS
 
@@ -38,14 +37,17 @@ struct _GtkListItemFactoryClass
 
   /* setup @list_item so it can be bound */
   void                  (* setup)                               (GtkListItemFactory     *self,
+                                                                 GtkListItemWidget      *widget,
                                                                  GtkListItem            *list_item);
   /* undo the effects of GtkListItemFactoryClass::setup() */
   void                  (* teardown)                            (GtkListItemFactory     *self,
+                                                                 GtkListItemWidget      *widget,
                                                                  GtkListItem            *list_item);
 
   /* Update properties on @list_item to the given @item, which is in @position and @selected state.
    * One or more of those properties might be unchanged. */
   void                  (* update)                              (GtkListItemFactory     *self,
+                                                                 GtkListItemWidget      *widget,
                                                                  GtkListItem            *list_item,
                                                                  guint                   position,
                                                                  gpointer                item,
@@ -53,12 +55,12 @@ struct _GtkListItemFactoryClass
 };
 
 void                    gtk_list_item_factory_setup             (GtkListItemFactory     *self,
-                                                                 GtkListItem            *list_item);
+                                                                 GtkListItemWidget      *widget);
 void                    gtk_list_item_factory_teardown          (GtkListItemFactory     *self,
-                                                                 GtkListItem            *list_item);
+                                                                 GtkListItemWidget      *widget);
 
 void                    gtk_list_item_factory_update            (GtkListItemFactory     *self,
-                                                                 GtkListItem            *list_item,
+                                                                 GtkListItemWidget      *widget,
                                                                  guint                   position,
                                                                  gpointer                item,
                                                                  gboolean                selected);
index 5912e406bea72fc8a1c67104d36734fecd4c8c96..b84057f83829fed211062750400b5475d0cf0076 100644 (file)
@@ -41,7 +41,7 @@ struct _GtkListItem
   guint selected : 1;
 };
 
-GtkListItem *   gtk_list_item_new                               (GtkListItemWidget      *owner);
+GtkListItem *   gtk_list_item_new                               (void);
 
 void            gtk_list_item_set_item                          (GtkListItem            *self,
                                                                  gpointer                item);
index dcd0e2f3cf828f456aa563d3b48f095c7736d404..8481054e7280ac09f24b66b54c6df92afb7a1386 100644 (file)
@@ -106,9 +106,8 @@ gtk_list_item_widget_dispose (GObject *object)
 
   if (self->item)
     {
-      gtk_list_item_factory_teardown (self->factory, self->item);
-      self->item->owner = NULL;
-      g_clear_object (&self->item);
+      gtk_list_item_factory_teardown (self->factory, self);
+      g_assert (self->item == NULL);
     }
   g_clear_object (&self->factory);
 
@@ -313,8 +312,6 @@ gtk_list_item_widget_init (GtkListItemWidget *self)
   controller = gtk_event_controller_focus_new ();
   g_signal_connect (controller, "enter", G_CALLBACK (gtk_list_item_widget_enter_cb), self);
   gtk_widget_add_controller (GTK_WIDGET (self), controller);
-
-  self->item = gtk_list_item_new (self);
 }
 
 GtkWidget *
@@ -332,7 +329,8 @@ gtk_list_item_widget_new (GtkListItemFactory *factory,
     {
       result->factory = g_object_ref (factory);
 
-      gtk_list_item_factory_setup (factory, result->item);
+      gtk_list_item_factory_setup (factory, result);
+      g_assert (result->item != NULL);
     }
 
   return GTK_WIDGET (result);
@@ -344,7 +342,8 @@ gtk_list_item_widget_update (GtkListItemWidget *self,
                              gpointer           item,
                              gboolean           selected)
 {
-  gtk_list_item_factory_update (self->factory, self->item, position, item, selected);
+  if (self->factory)
+    gtk_list_item_factory_update (self->factory, self, position, item, selected);
 
   if (selected)
     gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED, FALSE);
@@ -352,6 +351,42 @@ gtk_list_item_widget_update (GtkListItemWidget *self,
     gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED);
 }
 
+void
+gtk_list_item_widget_default_setup (GtkListItemWidget *self,
+                                    GtkListItem       *list_item)
+{
+  self->item = list_item;
+  list_item->owner = self;
+
+  if (list_item->child)
+    gtk_list_item_widget_add_child (self, list_item->child);
+}
+
+void
+gtk_list_item_widget_default_teardown (GtkListItemWidget *self,
+                                       GtkListItem       *list_item)
+{
+  g_assert (self->item == list_item);
+
+  self->item = NULL;
+  list_item->owner = NULL;
+
+  if (list_item->child)
+    gtk_list_item_widget_remove_child (self, list_item->child);
+}
+
+void
+gtk_list_item_widget_default_update (GtkListItemWidget *self,
+                                     GtkListItem       *list_item,
+                                     guint              position,
+                                     gpointer           item,
+                                     gboolean           selected)
+{
+  gtk_list_item_set_item (list_item, item);
+  gtk_list_item_set_position (list_item, position);
+  gtk_list_item_set_selected (list_item, selected);
+}
+
 void
 gtk_list_item_widget_add_child (GtkListItemWidget *self,
                                 GtkWidget         *child)
@@ -366,6 +401,12 @@ gtk_list_item_widget_remove_child (GtkListItemWidget *self,
   gtk_widget_unparent (child);
 }
 
+GtkListItem *
+gtk_list_item_widget_get_list_item (GtkListItemWidget *self)
+{
+  return self->item;
+}
+
 guint
 gtk_list_item_widget_get_position (GtkListItemWidget *self)
 {
index b3289b139e1f168f07d79cf77ee37c856f9ba4ef..9b34e9f5d6251cfc352876772c8a2753111eda1a 100644 (file)
@@ -59,6 +59,17 @@ void                    gtk_list_item_widget_update             (GtkListItemWidg
                                                                  guint                   position,
                                                                  gpointer                item,
                                                                  gboolean                selected);
+GtkListItem *           gtk_list_item_widget_get_list_item      (GtkListItemWidget      *self);
+
+void                    gtk_list_item_widget_default_setup      (GtkListItemWidget      *self,
+                                                                 GtkListItem            *list_item);
+void                    gtk_list_item_widget_default_teardown   (GtkListItemWidget      *self,
+                                                                 GtkListItem            *list_item);
+void                    gtk_list_item_widget_default_update     (GtkListItemWidget      *self,
+                                                                 GtkListItem            *list_item,
+                                                                 guint                   position,
+                                                                 gpointer                item,
+                                                                 gboolean                selected);
 
 void                    gtk_list_item_widget_add_child          (GtkListItemWidget      *self,
                                                                  GtkWidget              *child);
index 467b55d5400b4e437d0a3a3bb1f14335f639d353..c1c8ada1f6327367907cbab961b5c54bf0d3e352 100644 (file)
@@ -81,18 +81,14 @@ struct _GtkSignalListItemFactoryClass
 {
   GtkListItemFactoryClass parent_class;
 
-  void                  (* setup)                               (GtkListItemFactory     *self,
-                                                                 GtkListItem            *list_item);
-  void                  (* teardown)                            (GtkListItemFactory     *self,
-                                                                 GtkListItem            *list_item);
-
-  void                  (* bind)                                (GtkListItemFactory     *self,
-                                                                 GtkListItem            *list_item,
-                                                                 guint                   position,
-                                                                 gpointer                item,
-                                                                 gboolean                selected);
-  void                  (* unbind)                              (GtkListItemFactory     *self,
-                                                                 GtkListItem            *list_item);
+  void                  (* setup)                               (GtkSignalListItemFactory *self,
+                                                                 GtkListItem              *list_item);
+  void                  (* teardown)                            (GtkSignalListItemFactory *self,
+                                                                 GtkListItem              *list_item);
+  void                  (* bind)                                (GtkSignalListItemFactory *self,
+                                                                 GtkListItem              *list_item);
+  void                  (* unbind)                              (GtkSignalListItemFactory *self,
+                                                                 GtkListItem              *list_item);
 };
 
 enum {
@@ -109,15 +105,20 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 static void
 gtk_signal_list_item_factory_setup (GtkListItemFactory *factory,
+                                    GtkListItemWidget  *widget,
                                     GtkListItem        *list_item)
 {
-  GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->setup (factory, list_item);
-
   g_signal_emit (factory, signals[SETUP], 0, list_item);
+
+  GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->setup (factory, widget, list_item);
+
+  if (gtk_list_item_get_item (list_item))
+    g_signal_emit (factory, signals[BIND], 0, list_item);
 }
 
 static void                  
 gtk_signal_list_item_factory_update (GtkListItemFactory *factory,
+                                     GtkListItemWidget  *widget,
                                      GtkListItem        *list_item,
                                      guint               position,
                                      gpointer            item,
@@ -126,7 +127,7 @@ gtk_signal_list_item_factory_update (GtkListItemFactory *factory,
   if (gtk_list_item_get_item (list_item))
     g_signal_emit (factory, signals[UNBIND], 0, list_item);
 
-  GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->update (factory, list_item, position, item, selected);
+  GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected);
 
   if (item)
     g_signal_emit (factory, signals[BIND], 0, list_item);
@@ -134,14 +135,15 @@ gtk_signal_list_item_factory_update (GtkListItemFactory *factory,
 
 static void
 gtk_signal_list_item_factory_teardown (GtkListItemFactory *factory,
+                                       GtkListItemWidget  *widget,
                                        GtkListItem        *list_item)
 {
   if (gtk_list_item_get_item (list_item))
     g_signal_emit (factory, signals[UNBIND], 0, list_item);
 
-  g_signal_emit (factory, signals[TEARDOWN], 0, list_item);
+  GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->teardown (factory, widget, list_item);
 
-  GTK_LIST_ITEM_FACTORY_CLASS (gtk_signal_list_item_factory_parent_class)->teardown (factory, list_item);
+  g_signal_emit (factory, signals[TEARDOWN], 0, list_item);
 }
 
 static void